{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import pprint\n",
    "import tempfile\n",
    "\n",
    "from typing import Dict, Text\n",
    "\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import tensorflow_datasets as tfds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow_recommenders as tfrs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 小型数据 推荐算法原理设计\n",
    "# 电影数据 电影名称 类别 导演 时间 演员\n",
    "# 用户数据 uid 收藏电影 电影评分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据库查询 pymysql\n",
    "\n",
    "import pymysql as sql\n",
    "db = sql.connect(host='xmu-maker.cn',user='root', password='zq',port=3306)\n",
    "cursor = db.cursor()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cursor.execute(\"use films\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, '扬名立万', '/films/1413641', 'https://p0.meituan.net/movie/dcc0411b145d4336a7f67e650d17964e1846717.jpg@218w_300h_1e_1c', '悬疑/喜剧/剧情', '尹正/邓家佳/喻恩泰', '2021/11/11 18:00')\n"
     ]
    }
   ],
   "source": [
    "# 电影数据处理\n",
    "sql_cmd = 'select * from movies'\n",
    "cursor.execute(sql_cmd)\n",
    "result = cursor.fetchall()\n",
    "print(result[1], )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['扬名立万', '悬疑/喜剧/剧情', '尹正/邓家佳/喻恩泰']\n",
      "<TensorSliceDataset shapes: (3,), types: tf.string>\n"
     ]
    }
   ],
   "source": [
    "res = list(map(lambda x: tf.convert_to_tensor([x[1],x[4],x[5]]), result))\n",
    "movies_dataset = tf.data.Dataset.from_tensor_slices(res)\n",
    "\n",
    "\n",
    "movies = list(map(lambda x:[x[1],x[4], x[5]], result))\n",
    "pprint.pprint(movies[1])\n",
    "print(movies_dataset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42894"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "movie_titles_vocabulary = tf.keras.layers.StringLookup(mask_token=None)\n",
    "movie_titles_vocabulary.adapt(movies_dataset)\n",
    "movie_titles_vocabulary.vocabulary_size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "embeding_dim = 32"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Model was constructed with shape (None,) for input KerasTensor(type_spec=TensorSpec(shape=(None,), dtype=tf.string, name='string_lookup_7_input'), name='string_lookup_7_input', description=\"created by layer 'string_lookup_7_input'\"), but it was called on an input with incompatible shape (None, 3).\n"
     ]
    }
   ],
   "source": [
    "movie_model = tf.keras.Sequential([\n",
    "    movie_titles_vocabulary,\n",
    "    tf.keras.layers.Embedding(movie_titles_vocabulary.vocabulary_size(), embeding_dim)\n",
    "])\n",
    "movies_embeding = movie_model.predict(movies)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "21678\n",
      "array([[ 0.02894459, -0.00216864,  0.04384849,  0.00023314,  0.00125909,\n",
      "        -0.0376228 , -0.04181495, -0.01056314, -0.03466325,  0.0032535 ,\n",
      "        -0.01234416,  0.02800805, -0.02936714, -0.01192983, -0.04618927,\n",
      "         0.00790792,  0.03907594,  0.04191159, -0.01728693, -0.0285234 ,\n",
      "        -0.02143122,  0.0232215 , -0.01429073,  0.04096423, -0.01761087,\n",
      "         0.02093896, -0.02695845,  0.04474664,  0.0160309 ,  0.02749549,\n",
      "        -0.03726555,  0.01161494],\n",
      "       [-0.03952644, -0.03777479, -0.00771812,  0.00209615, -0.04252644,\n",
      "         0.04017121, -0.04701893,  0.04479888, -0.00640779,  0.04220081,\n",
      "         0.04109347, -0.00256252, -0.01566233, -0.04749259, -0.01821467,\n",
      "        -0.01672667,  0.01546358, -0.01247741,  0.03116858,  0.02840212,\n",
      "         0.00275712, -0.03184017,  0.00612594,  0.0352308 , -0.03911693,\n",
      "         0.02183561,  0.01880089,  0.04940777,  0.04862188,  0.00820788,\n",
      "        -0.0216508 ,  0.02188333],\n",
      "       [ 0.02035454, -0.03066354,  0.04030105,  0.02105255, -0.01450657,\n",
      "        -0.0135157 , -0.0368553 ,  0.04655779, -0.04893417, -0.04979689,\n",
      "        -0.01409661,  0.0033383 ,  0.01739517, -0.01741043,  0.01216099,\n",
      "        -0.03634325, -0.03598868, -0.01889259,  0.0373703 , -0.01011639,\n",
      "         0.01939503,  0.02304446, -0.02504245,  0.03641859, -0.04533381,\n",
      "        -0.00160281,  0.01359925, -0.02615149, -0.0323362 , -0.03349053,\n",
      "         0.0179412 ,  0.03740759]], dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "# np.save('movies1.npy', movies_embeding)\n",
    "print(len(movies_embeding))\n",
    "pprint.pprint(movies_embeding[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.02509674, -0.03233554,  0.01738966,  0.00246248,  0.02821661,\n",
       "        0.04408883,  0.01748705, -0.02144954,  0.01236815,  0.03181155,\n",
       "        0.02543769,  0.04083734,  0.04905597,  0.04095783,  0.04518214,\n",
       "        0.0388343 , -0.00379945, -0.04453652, -0.02332424,  0.04352602,\n",
       "       -0.01262826,  0.03656875,  0.03830924,  0.04202136, -0.03005455,\n",
       "        0.00716317, -0.02710382, -0.03534471,  0.03000126, -0.04023731,\n",
       "        0.04553436, -0.02942351], dtype=float32)"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "movies_embeding[0][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [],
   "source": [
    "def euclidean_distance_by_tf(vector1, vector2):\n",
    "    return tf.sqrt(tf.reduce_sum(tf.square(vector1 - vector2)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tf.Tensor(0.22042648, shape=(), dtype=float32)\n",
      "tf.Tensor(0.2649098, shape=(), dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "print(euclidean_distance_by_tf(movies_embeding[2][1],movies_embeding[4][1]))\n",
    "print(euclidean_distance_by_tf(movies_embeding[335][1],movies_embeding[336][1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3,\n",
      " '不速来客',\n",
      " '/films/1310437',\n",
      " 'https://p0.meituan.net/movie/6ff6096575c4879b9209e88a13bd306b5068603.jpg@218w_300h_1e_1c',\n",
      " '悬疑/喜剧',\n",
      " '范伟/窦骁/张颂文',\n",
      " '2021/10/22')\n"
     ]
    }
   ],
   "source": [
    "# 用户数据处理\n",
    "uid = 5\n",
    "sql_cmd = 'select * from movies where mid in (select mid from user_collect where uid = 5)'\n",
    "cursor.execute(sql_cmd)\n",
    "collection = cursor.fetchall()\n",
    "pprint.pprint(collection[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<TensorSliceDataset shapes: (), types: tf.string>\n"
     ]
    }
   ],
   "source": [
    "collect = list(map(lambda x: tf.convert_to_tensor(f\"{x[1]}:{x[4]}:{x[5]}\"), collection)) // 导演 \n",
    "ratings = list(map(lambda x: {\n",
    "    \"user_id\": tf.convert_to_tensor(f'{x[1]}:{x[4]}:{x[5]}')\n",
    "    }, collection))\n",
    "\n",
    "collect = tf.data.Dataset.from_tensor_slices(collect)\n",
    "pprint.pprint(collect)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['3:不速来客:悬疑/喜剧:范伟/窦骁/张颂文', '4:门锁:悬疑/惊悚:孔晓振/金叡园/金圣武', '154:招魂:恐怖/惊悚/剧情:维拉·法梅加/帕特里克·威尔森/莉莉·泰勒', '337:明天你是否依然爱我:剧情/爱情:杨颖/李鸿其/黄柏钧', '188:比悲伤更悲伤的故事:剧情/爱情:陈意涵/刘以豪/张书豪']\n"
     ]
    }
   ],
   "source": [
    "print(ratings)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "user_ids_vocabulary = tf.keras.layers.StringLookup(mask_token=None)\n",
    "user_ids_vocabulary.adapt(collect)  # 将字符串映射到整数中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "user_model = tf.keras.Sequential([\n",
    "    user_ids_vocabulary,\n",
    "    tf.keras.layers.Embedding(user_ids_vocabulary.vocabulary_size(), 64) # 维度为64\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-2.04668175e-02  7.93625973e-03  1.99608002e-02  2.66758408e-02\n",
      "  1.63849052e-02 -1.26919420e-02  5.75738400e-03  1.52354762e-02\n",
      "  8.73644277e-03 -1.39451949e-02  7.99781084e-03  6.66861888e-03\n",
      "  1.42345084e-02  1.34704858e-02  1.67987496e-03  1.36139514e-02\n",
      " -5.66788390e-03 -2.01227330e-02 -5.91014512e-03  1.54681848e-02\n",
      " -1.10786315e-02  1.44444704e-02 -3.67090176e-03 -2.13060174e-02\n",
      "  6.53608609e-03 -2.21240520e-02 -1.51207449e-03  8.01825244e-03\n",
      "  1.84849221e-02  2.86547421e-03 -1.53358905e-02 -1.96176325e-03\n",
      "  1.49046779e-02 -6.83440873e-03 -1.14822127e-02 -1.84229501e-02\n",
      "  9.83822532e-03 -2.05061585e-02 -1.99809674e-05  5.26313484e-03\n",
      "  1.60331279e-03 -1.48924561e-02  2.63396022e-03  6.05566613e-03\n",
      "  2.33743154e-02 -1.44800795e-02  3.76438955e-03  1.09591130e-02\n",
      " -1.67269562e-03 -6.41966518e-03 -1.36436671e-02 -1.94781441e-02\n",
      "  2.87662745e-02 -3.78489424e-03 -1.88145619e-02  1.83478149e-03\n",
      " -3.35157802e-03  3.39296903e-03 -2.99171917e-02 -1.44522935e-02\n",
      " -1.14920158e-02 -7.89506640e-03 -7.06809619e-03  3.34848603e-03]\n"
     ]
    }
   ],
   "source": [
    "user_embeddings = user_model.predict(ratings)\n",
    "# print(user_embeddings)\n",
    "\n",
    "\n",
    "print(np.mean(user_embeddings, axis=0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 231,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MovieLensModel(tfrs.Model):\n",
    "  # We derive from a custom base class to help reduce boilerplate. Under the hood,\n",
    "  # these are still plain Keras Models.\n",
    "\n",
    "  def __init__(\n",
    "      self,\n",
    "      user_model: tf.keras.Model,\n",
    "      movie_model: tf.keras.Model,\n",
    "      task: tfrs.tasks.Retrieval):\n",
    "    super().__init__()\n",
    "\n",
    "    # Set up user and movie representations.\n",
    "    self.user_model = user_model\n",
    "    self.movie_model = movie_model\n",
    "\n",
    "    # Set up a retrieval task.\n",
    "    self.task = task\n",
    "\n",
    "  def compute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor:\n",
    "    # Define how the loss is computed.\n",
    "\n",
    "    user_embeddings = self.user_model(features[\"user_id\"])\n",
    "    movie_embeddings = self.movie_model(features[\"movie_title\"])\n",
    "\n",
    "    return self.task(user_embeddings, movie_embeddings)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 232,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define user and movie models.\n",
    "\n",
    "\n",
    "\n",
    "# Define your objectives. # 选择模型指标， \n",
    "task = tfrs.tasks.Retrieval(metrics=tfrs.metrics.FactorizedTopK(\n",
    "    dataset.batch(128).map(movie_model)\n",
    "  )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a retrieval model.\n",
    "model = MovieLensModel(user_model, movie_model, task)\n",
    "model.compile(optimizer=tf.keras.optimizers.Adagrad(0.5)) # 模型编译\n",
    "\n",
    "# Train for 3 epochs.\n",
    "model.fit(coll, epochs=3) # 模型训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 233,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/3\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "in user code:\n\n    File \"D:\\Anaconda\\envs\\tf\\lib\\site-packages\\keras\\engine\\training.py\", line 878, in train_function  *\n        return step_function(self, iterator)\n    File \"D:\\Anaconda\\envs\\tf\\lib\\site-packages\\keras\\engine\\training.py\", line 867, in step_function  **\n        outputs = model.distribute_strategy.run(run_step, args=(data,))\n    File \"D:\\Anaconda\\envs\\tf\\lib\\site-packages\\keras\\engine\\training.py\", line 860, in run_step  **\n        outputs = model.train_step(data)\n    File \"D:\\Anaconda\\envs\\tf\\lib\\site-packages\\tensorflow_recommenders\\models\\base.py\", line 68, in train_step\n        loss = self.compute_loss(inputs, training=True)\n    File \"C:\\Users\\36014\\AppData\\Local\\Temp/ipykernel_18408/3400292400.py\", line 22, in compute_loss\n        user_embeddings = self.user_model(features[\"user_id\"])\n\n    TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got 'user_id'\n",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_18408/1306410688.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;31m# Train for 3 epochs.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0mmodel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcoll\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mepochs\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# 模型训练\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      7\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[1;31m# Use brute-force search to set up retrieval using the trained representations.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mD:\\Anaconda\\envs\\tf\\lib\\site-packages\\keras\\utils\\traceback_utils.py\u001b[0m in \u001b[0;36merror_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m     65\u001b[0m     \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m  \u001b[1;31m# pylint: disable=broad-except\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     66\u001b[0m       \u001b[0mfiltered_tb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_process_traceback_frames\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__traceback__\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 67\u001b[1;33m       \u001b[1;32mraise\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwith_traceback\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfiltered_tb\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     68\u001b[0m     \u001b[1;32mfinally\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     69\u001b[0m       \u001b[1;32mdel\u001b[0m \u001b[0mfiltered_tb\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mD:\\Anaconda\\envs\\tf\\lib\\site-packages\\tensorflow\\python\\framework\\func_graph.py\u001b[0m in \u001b[0;36mautograph_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m   1127\u001b[0m           \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m  \u001b[1;31m# pylint:disable=broad-except\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   1128\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0me\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"ag_error_metadata\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1129\u001b[1;33m               \u001b[1;32mraise\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mag_error_metadata\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto_exception\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0me\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m   1130\u001b[0m             \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   1131\u001b[0m               \u001b[1;32mraise\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTypeError\u001b[0m: in user code:\n\n    File \"D:\\Anaconda\\envs\\tf\\lib\\site-packages\\keras\\engine\\training.py\", line 878, in train_function  *\n        return step_function(self, iterator)\n    File \"D:\\Anaconda\\envs\\tf\\lib\\site-packages\\keras\\engine\\training.py\", line 867, in step_function  **\n        outputs = model.distribute_strategy.run(run_step, args=(data,))\n    File \"D:\\Anaconda\\envs\\tf\\lib\\site-packages\\keras\\engine\\training.py\", line 860, in run_step  **\n        outputs = model.train_step(data)\n    File \"D:\\Anaconda\\envs\\tf\\lib\\site-packages\\tensorflow_recommenders\\models\\base.py\", line 68, in train_step\n        loss = self.compute_loss(inputs, training=True)\n    File \"C:\\Users\\36014\\AppData\\Local\\Temp/ipykernel_18408/3400292400.py\", line 22, in compute_loss\n        user_embeddings = self.user_model(features[\"user_id\"])\n\n    TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got 'user_id'\n"
     ]
    }
   ],
   "source": [
    "# Use brute-force search to set up retrieval using the trained representations.\n",
    "index = tfrs.layers.factorized_top_k.BruteForce(model.user_model)\n",
    "index.index_from_dataset(\n",
    "    dataset.batch(100).map(lambda title: (title, model.movie_model(title))))\n",
    "\n",
    "# Get some recommendations.\n",
    "_, titles = index(np.array([\"42\"]))\n",
    "print(f\"Top 3 recommendations for user 42: {titles[0, :3]}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "06b4f7c561f76ad499c5882876df75324df0d287869e55b80005d36e4919f42b"
  },
  "kernelspec": {
   "display_name": "Python 3.9.7 64-bit ('tf': conda)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
